import 'package:dio/dio.dart';
import 'package:get_it/get_it.dart';

import '../network/dio_client.dart';
import '../utils/rate_limiter.dart';
import '../../data/datasources/anime_remote_datasource.dart';
import '../../data/datasources/anime_local_datasource.dart';
import '../../data/datasources/favorite_local_datasource.dart';
import '../../data/repositories/anime_repository_impl.dart';
import '../../data/repositories/favorite_repository_impl.dart';
import '../../domain/repositories/anime_repository.dart';
import '../../domain/repositories/favorite_repository.dart';
import '../../presentation/providers/anime_provider.dart';
import '../../presentation/providers/favorite_provider.dart';
import '../../presentation/providers/content_filter_provider.dart';

final getIt = GetIt.instance;

/// 初始化依赖注入
Future<void> setupServiceLocator() async {
  // 网络层
  getIt.registerLazySingleton<DioClient>(() => DioClient());
  getIt.registerLazySingleton<Dio>(() => getIt<DioClient>().dio);
  getIt.registerLazySingleton<RateLimiter>(() => RateLimiter());

  // 数据源
  getIt.registerLazySingleton<AnimeRemoteDataSource>(
    () => AnimeRemoteDataSource(
      dio: getIt<Dio>(),
      rateLimiter: getIt<RateLimiter>(),
    ),
  );

  // 本地数据源需要初始化
  final animeLocalDataSource = AnimeLocalDataSource();
  await animeLocalDataSource.init();
  getIt.registerLazySingleton<AnimeLocalDataSource>(() => animeLocalDataSource);

  // 收藏本地数据源
  final favoriteLocalDataSource = FavoriteLocalDataSource();
  await favoriteLocalDataSource.init();
  getIt.registerLazySingleton<FavoriteLocalDataSource>(() => favoriteLocalDataSource);

  // 内容过滤Provider
  final contentFilterProvider = ContentFilterProvider();
  await contentFilterProvider.init();
  getIt.registerLazySingleton<ContentFilterProvider>(() => contentFilterProvider);

  // 仓库
  getIt.registerLazySingleton<AnimeRepository>(
    () => AnimeRepositoryImpl(
      remoteDataSource: getIt<AnimeRemoteDataSource>(),
      localDataSource: getIt<AnimeLocalDataSource>(),
    ),
  );

  getIt.registerLazySingleton<FavoriteRepository>(
    () => FavoriteRepositoryImpl(
      localDataSource: getIt<FavoriteLocalDataSource>(),
      animeLocalDataSource: getIt<AnimeLocalDataSource>(),
    ),
  );

  // Providers
  getIt.registerFactory<AnimeProvider>(
    () => AnimeProvider(
      getIt<AnimeRepository>(),
      getIt<AnimeLocalDataSource>(),
      getIt<ContentFilterProvider>(),
    ),
  );

  getIt.registerFactory<FavoriteProvider>(
    () => FavoriteProvider(getIt<FavoriteRepository>()),
  );
} 